﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Xml.Serialization;
using SharpMap.Geometries;
using System.Data;

namespace Hanhud
{
    public class CLocation : IXmlSerializable
    {
        #region Properties
        private int _locationID = -1;
        public int LocationID { get { return _locationID; } protected set { _locationID = value; } }

        private int _provinceCode = -1;
        public int ProvinceCode { get { return _provinceCode; } set { _provinceCode = value; } }

        private int _districtCode = -1;
        public int DistrictCode { get { return _districtCode; } set { _districtCode = value; } }

        private int _communeCode = -1;
        public int CommuneCode { get { return _communeCode; } set { _communeCode = value; } }

        private string _name = string.Empty;
        public string Name { get { return _name; } set { _name = value; } }

        private string _fullName = string.Empty;
        public string FullName { get { return _fullName; } set { _fullName = value; } }

        private string _title = string.Empty;
        public string Title { get { return _title; } protected set { _title = value; } }

        private Geometry _geom = null;
        public Geometry Geom { get { return _geom; } }

        #endregion

        #region Constructors
        public CLocation(int locationID)
        {
            this.LocationID = locationID;
        }

        public CLocation(string name, string fullName, int provinceCode, int districtCode, int communeCode)
        {
            this.Name = name;
            this.FullName = fullName;
            this.ProvinceCode = provinceCode;
            this.DistrictCode = districtCode;
            this.CommuneCode = communeCode;
        }

        internal CLocation(int locationID, string name, string fullName, string title, int provinceCode, int districtCode, int communeCode)
            : this(name, fullName, provinceCode, districtCode, communeCode)
        {
            this.LocationID = locationID;
            this.Title = title;
        }
        #endregion

        #region XmlSerializable
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteStartElement("location");

            // Location id
            writer.WriteStartAttribute("locationID");
            writer.WriteValue(this.LocationID);
            writer.WriteEndAttribute();

            writer.WriteStartElement("provinceCode");
            writer.WriteValue(this.ProvinceCode);
            writer.WriteEndElement();

            writer.WriteStartElement("districtCode");
            writer.WriteValue(this.DistrictCode);
            writer.WriteEndElement();

            writer.WriteStartElement("communeCode");
            writer.WriteValue(this.CommuneCode);
            writer.WriteEndElement();

            writer.WriteStartElement("name");
            writer.WriteValue(this.Name);
            writer.WriteEndElement();

            writer.WriteEndElement();
        } 
        #endregion

        #region Override methods
        public override bool Equals(object obj)
        {
            return ((CLocation)obj).LocationID == LocationID;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return base.ToString();
        } 
        #endregion

        public static CLocation GetLocationInfo(int locationID)
        {
            return GetLocationFromTable(Data.Providers.CProvider.Instance.GetLocationInfo(locationID));
        }

        public static LocationCollection GetLocations()
        {
            LocationCollection locationList = new LocationCollection();

            foreach(DataRow row in Data.Providers.CProvider.Instance.GetLocations(-1, -1).Rows)
                locationList.Add(GetLocationFromTable(row));

            return locationList;
        }

        public static LocationCollection GetLocations(int provinceCode)
        {
            LocationCollection locationList = new LocationCollection();

            foreach (DataRow row in Data.Providers.CProvider.Instance.GetLocations(provinceCode, -1).Rows)
                locationList.Add(GetLocationFromTable(row));

            return locationList;
        }

        public static LocationCollection GetLocations(int provinceCode, int districtCode)
        {
            LocationCollection locationList = new LocationCollection();

            foreach (DataRow row in Data.Providers.CProvider.Instance.GetLocations(provinceCode, districtCode).Rows)
                locationList.Add(GetLocationFromTable(row));

            return locationList;
        }

        public static CLocation GetLocationInfo(int provinceCode, int districtCode, int communeCode)
        {
            return GetLocationFromTable(Data.Providers.CProvider.Instance.GetLocationInfo(provinceCode, districtCode, communeCode));
        }

        private static CLocation GetLocationFromTable(DataRow row)
        {
            return row == null ? null :
                new CLocation(
                    (int)row["LocationID"],
                    row["Name"].ToString(),
                    row["FullName"].ToString(),
                    row["Title"].ToString(),
                    (int)row["ProvinceCode"],
                    (int)row["DistrictCode"],
                    (int)row["CommuneCode"]);
        }
    }

    public class LocationCollection : List<CLocation>, IXmlSerializable
    {
        public LocationCollection()
        {
        }

        public LocationCollection(IEnumerable<CLocation> collection)
            : base(collection)
        {
            
        }

        #region XmlSerializable
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteStartElement("locationCollection");

            foreach (CLocation location in  this)
            {
                location.WriteXml(writer);
            }

            writer.WriteEndElement();
        } 
        #endregion
    }
}